package com.chenxinzhimusic.viewmodel

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.media3.common.Player
import com.chenxinzhimusic.data.getDataContentValue
import com.chenxinzhimusic.data.loveKey
import com.chenxinzhimusic.data.musicSettingKey
import com.chenxinzhimusic.data.playListKey
import com.chenxinzhimusic.data.saveDataContent
import com.chenxinzhimusic.refreshFlow
import com.chenxinzhimusic.service.MusicService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable

@Serializable
data class MusicInfo(
    var musicId: String,
    var title: String,
    var artist: String,
    var picUrl: String,
    var duration: Int = 0,
    var position: Int = 0,
    var lycUrl: String = "",
    var album: String = "",

    )
fun Abslist.toMusicInfo()=
    MusicInfo( dCTARGETID,
        nAME,
        aRTIST,
        if (webAlbumpicShort.isBlank()) {
            "https://img1.kuwo.cn/star/starheads/${webArtistpicShort}"
        } else {
            "https://img2.kuwo.cn/star/albumcover/${webAlbumpicShort}"
        }.replace("/120/", "/1000/"),
        dURATION.toInt(),
        0,
        "",
        aLBUM)


@Serializable
data class MusicSetting(
    var currentMusic: MusicInfo,
    var playList: PlayList,
    var isPlay: Boolean = false,
    var repeatMode: Int = Player.REPEAT_MODE_ALL,
    var shuffle: Boolean = false
)

@Serializable
data class PlayList(
    var id: Int = 0,
    var name: String = "默认列表",
    var musicList: MutableList<MusicInfo>
)

val lock = Mutex()
suspend fun Context.addMusic(musicInfo: MusicInfo) = withContext(Dispatchers.IO) {
    lock.withLock {
        var key = playListKey
        var dataContentValue = getDataContentValue<PlayList>(key)
        saveDataContent(musicSettingKey, (dataContentValue?.let {
            if (!(it.musicList.contains(musicInfo))) {
                it.musicList.add(musicInfo.copy())
            }
            MusicSetting(musicInfo, it)
        } ?: MusicSetting(musicInfo, PlayList(musicList = mutableListOf(musicInfo.copy())))).apply {
            launch(Dispatchers.Main) {
                MusicService.playList(
                    currentMusic,
                    playList.musicList,
                )
            }
            saveDataContent(key, playList)
        })
    }
}

suspend fun Context.addMusic(musicInfo: MusicInfo, playList: PlayList) =
    withContext(Dispatchers.IO) {
        lock.withLock {
            var key = playListKey
            var dataContentValue = playList
            saveDataContent(musicSettingKey, dataContentValue.let {
                if (!(it.musicList.map { it.musicId }.contains(musicInfo.musicId))) {
                    it.musicList.add(musicInfo.copy())
                }
                MusicSetting(musicInfo, it)
            }.apply {
                launch(Dispatchers.Main) {
                    MusicService.playList(
                        currentMusic,
                        playList.musicList
                    )
                }
                saveDataContent(key, playList)
            })
        }
    }

suspend inline fun <reified T> Context.getMusic(key: Preferences.Key<String>): T? {
    return withContext(Dispatchers.IO) {
        getDataContentValue<T>(key)
    }
}

suspend inline fun Context.removeMusic(key: Preferences.Key<String>, musicId: String) {
    return withContext(Dispatchers.IO) {
        getDataContentValue<PlayList>(key)?.apply {
            musicList.removeIf { it.musicId == musicId }
            saveDataContent(key, this)
            refreshFlow.emit(Unit)
        }
    }
}


suspend fun Context.updateMusicPos(time: Int, isPlay: Boolean, musicId: String,a: Int?,b: Boolean?) =
    withContext(Dispatchers.IO) {
        lock.withLock {
            var dataContentValue = getDataContentValue<MusicSetting>(musicSettingKey)
            dataContentValue?.apply {
                if (musicId != currentMusic.musicId) {
                    return@apply
                }
                currentMusic.position = time
                this.isPlay = isPlay
                if (b != null) {
                    shuffle = b
                }
                if (a != null) {
                    repeatMode = a
                }
                saveDataContent(musicSettingKey, this)
            }
        }
    }

suspend fun Context.addToLove(musicInfo: MusicInfo) = withContext(Dispatchers.IO) {

    var key = loveKey
    var dataContentValue = getDataContentValue<PlayList>(key)
    (dataContentValue ?: PlayList(2, "我喜欢", mutableListOf())).apply {
        if (!(musicList.contains(musicInfo))) {
            musicList.add(musicInfo.copy())
        }
        saveDataContent(key, this)
    }
}

